package com.ifish.leetcode.problem.algorithm;

import com.ifish.leetcode.problem.BaseLeetCodeProblem;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by iFish on 2017/7/9.
 */

public class _0008 extends BaseLeetCodeProblem {
    @Override
    public String title() {
        return "String to Integer (atoi)";
    }

    @Override
    public int difficulty() {
        return 1;
    }

    @Override
    public void run() {
        super.run();

        String test = "        -1231212323232sssss";
        int r = myAtoi(test);
//        int r2 = Integer.valueOf(test);
        printResult(r);
    }

    public int myAtoi(String s) {
        s = s.trim();
        int len = s.length();
        boolean minus = false;
        List<Integer> temp = new ArrayList<>();
        int result = 0;
        boolean started = false;
        try {
            for (int i = 0; i < len; i++) {
                char c = s.charAt(i);
                if (c == ' ' && !started) {
                    continue;
                }
                if (!started && (c == '-' || c == '+')) {
                    minus = c == '-';
                } else if (c < 48 || c > 57) {
                    break;
                } else {
                    temp.add(c - 48);
                }
                started = true;
            }
            for (int i = 0; i < temp.size(); i++) {
                // 溢出判断
                int plus = safeValue(temp.get(i) * multiple(10, temp.size() - i - 1, minus));
                result = safeAdd(result, plus);
            }
        } catch (Exception e) {
            return e.getMessage().equals("max") ? Integer.MAX_VALUE : Integer.MIN_VALUE;
        }
        return result;
    }

    private long multiple(int base, int multi, boolean minus) throws Exception {
        long val = minus ? -1 : 1;
        for (int i = 0; i < multi; i++) {
            val *= base;
            checkRange(val);
        }
        return val;
    }

    private int safeValue(long val) throws Exception {
        checkRange(val);
        return (int)val;
    }

    private int safeAdd(long a, long b) throws Exception {
        long val = a + b;
        checkRange(val);
        return (int)val;
    }

    private void checkRange(long val) throws Exception {
        if (val > Integer.MAX_VALUE) {
            throw new Exception("max");
        } else if (val < Integer.MIN_VALUE) {
            throw new Exception("min");
        }
    }
}
